package zwxsrv

import (
	"fmt"
	"log"
	"net/http"
	"time"
)

type Cfg struct {
	WxToken string // 对接微信服务器的 token，注意和 access_token 区分开

	AppId       string
	Appsecret   string
	AdminOpenID string // 管理员的 open_id
}

var (
	gCfg            Cfg
	gLastReqMsgTime time.Duration

	gAccessTokenMan *AccessTokenMan
	gWxHandlerMan   *WxHandlerMan
)

// 总的消息结构
type RequestBody struct {
	ToUserName   string
	FromUserName string
	CreateTime   time.Duration
	MsgType      string
	MsgId        int64

	Content string //文本

	PicUrl string //图片
	//MediaId      string

	//MediaId      string 	//语音
	Format      string
	Recognition string

	//MediaId      string 	//视频，小视频
	ThumMediaId string

	Location_X string //位置
	Location_Y string
	Scale      string
	Label      string

	Title       string //链接
	Description string
	Url         string

	Event    string //事件
	EventKey string

	MediaId string //共用字段

	IsVoice bool //自定义字段
}

// 总的 weixin 处理入口(业务无关)。
func HttpHandler(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()

	//判断url合法性
	if !validateUrl(w, r) {
		log.Println("error: validateUrl error")
		return
	}

	if r.Method == "POST" {
		requestBody, err := parseRequestBody(r)
		if err != nil {
			log.Println("parseRequestBody error:", err)
			return
		}

		//检查消息体格式错误
		if requestBody.FromUserName == "" {
			log.Println("weixin msg format error")
			return
		}

		//终止直接回复
		w.Header().Set("Content-Type", "text/xml")
		fmt.Fprintf(w, "success")

		log.Printf("Wechat Service: Recv msg [%s] from user [%s]\n", requestBody.Content, requestBody.FromUserName)

		//判断消息重复
		if requestBody.CreateTime == gLastReqMsgTime {
			log.Println("weixin msg repeate")
			return
		}
		gLastReqMsgTime = requestBody.CreateTime

		//间接回复(处理业务逻辑)
		go nextHandler(requestBody)
		return
	}
}

// 初始化函数，应该在正式工作之前调用。
func Init(cfg *Cfg) {
	gCfg = *cfg

	// 1. 启动 access_token 更新服务
	gAccessTokenMan = NewAccessTokenMan(gCfg.AppId, gCfg.Appsecret)
	go gAccessTokenMan.Run()

	// 2. 准备 handler 注册
	gWxHandlerMan = NewWxHandlerMan()
}
